home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / unix / shel302a.3 < prev    next >
Text File  |  1989-03-15  |  54KB  |  1,951 lines

  1. Path: xanth!nic.MR.NET!hal!cwjcc!tut.cis.ohio-state.edu!bloom-beacon!apple!bbn!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i060:  shell - csh-like command interpreter v3.02a, Part03/03
  5. Message-ID: <12244@swan.ulowell.edu>
  6. Date: 15 Mar 89 19:40:06 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 1940
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: PERUGIA@ICNUCEVM.BITNET (Cesare Dieni)
  12. Posting-number: Volume 89, Issue 60
  13. Archive-name: unix/shell302a.3
  14.  
  15. #    This is a shell archive.
  16. #    Remove everything above and including the cut line.
  17. #    Then run the rest of the file through sh.
  18. #----cut here-----cut here-----cut here-----cut here----#
  19. #!/bin/sh
  20. # shar:    Shell Archiver
  21. #    Run the following text with /bin/sh to create:
  22. #    sub.c
  23. #    shell.doc
  24. # This archive created: Wed Mar 15 14:15:32 1989
  25. cat << \SHAR_EOF > sub.c
  26.  
  27. /*
  28.  * SUB.C
  29.  *
  30.  * (c)1986 Matthew Dillon     9 October 1986
  31.  *
  32.  * Version 2.07M by Steve Drew 10-Sep-87
  33.  *
  34.  * Version 3.02A by Carlo Borreo & Cesare Dieni 20-Dec-88
  35.  *
  36.  */
  37.  
  38. extern char *v_lasterr, *v_stat;
  39.  
  40. #define HM_STR 0              /* various HISTORY retrieval modes */
  41. #define HM_REL 1
  42. #define HM_ABS 2
  43.  
  44. /* extern BPTR Clock; */
  45.  
  46. seterr()
  47. {
  48. char buf[32];
  49. int stat;
  50.  
  51. sprintf(buf, "%d", Lastresult);
  52. set_var(LEVEL_SET, v_lasterr, buf);
  53. stat = atoi(get_var(LEVEL_SET, v_stat));
  54. if (stat < Lastresult) stat = Lastresult;
  55. sprintf(buf, "%d", stat);
  56. set_var(LEVEL_SET, v_stat, buf);
  57. }
  58.  
  59.  
  60. char *
  61. next_word(str)
  62. register char *str;
  63. {
  64.    while (*str  &&  *str != ' '  &&  *str != 9 && (unsigned char)*str != 0xA0)
  65.       ++str;
  66.    while (*str  && (*str == ' ' || *str == 9 || (unsigned char)*str == 0xA0))
  67.       ++str;
  68.    return (str);
  69. }
  70.  
  71. char *
  72. compile_av(av, start, end, delim)
  73. char **av;
  74. unsigned char delim;
  75. {
  76. char *cstr;
  77. int len;
  78. register unsigned int i;
  79.  
  80. len = 0;
  81. for (i = start; i < end; ++i) len += strlen(av[i]) + 1;
  82. cstr = malloc(len + 1);
  83. *cstr = '\0';
  84. for (i = start; i < end; ++i) {
  85.     if (debug) fprintf (stderr, "AV[%2d] :%s:\n", i, av[i]);
  86.     strcat (cstr, av[i]);
  87.     if (i + 1 < end) strncat(cstr, &delim, 1);
  88.     }
  89. return (cstr);
  90. }
  91.  
  92.  
  93. /*
  94.  * FREE(ptr)   --frees without actually freeing, so the data is still good
  95.  *               immediately after the free.
  96.  */
  97.  
  98.  
  99. Free(ptr)
  100. char *ptr;
  101. {
  102.    static char *old_ptr;
  103.  
  104.    if (old_ptr)
  105.       free (old_ptr);
  106.    old_ptr = ptr;
  107. }
  108.  
  109. /*
  110.  * Add new string to history (H_head, H_tail, H_len,
  111.  *  S_histlen
  112.  */
  113.  
  114. add_history(str)
  115. char *str;
  116. {
  117.    register struct HIST *hist;
  118.  
  119.    if (H_head != NULL && strcmp(H_head->line, str) == 0)
  120.        return(0);
  121.    while (H_len > S_histlen)
  122.       del_history();
  123.    hist = (struct HIST *)malloc (sizeof(struct HIST));
  124.    if (H_head == NULL) {
  125.       H_head = H_tail = hist;
  126.       hist->next = NULL;
  127.    } else {
  128.       hist->next = H_head;
  129.       H_head->prev = hist;
  130.       H_head = hist;
  131.    }
  132.    hist->prev = NULL;
  133.    hist->line = malloc (strlen(str) + 1);
  134.    strcpy (hist->line, str);
  135.    ++H_len;
  136. }
  137.  
  138. del_history()
  139. {
  140.    if (H_tail) {
  141.       --H_len;
  142.       ++H_tail_base;
  143.       free (H_tail->line);
  144.       if (H_tail->prev) {
  145.          H_tail = H_tail->prev;
  146.          free (H_tail->next);
  147.          H_tail->next = NULL;
  148.       } else {
  149.          free (H_tail);
  150.          H_tail = H_head = NULL;
  151.       }
  152.    }
  153. }
  154.  
  155. char *
  156. get_history(ptr)
  157. char *ptr;
  158. {
  159.    register struct HIST *hist;
  160.    register int len;
  161.    int mode = HM_REL;
  162.    int num  = 1;
  163.    char *str;
  164.    char *result = NULL;
  165.  
  166.    if (ptr[1] >= '0' && ptr[1] <= '9') {
  167.       mode = HM_ABS;
  168.       num  = atoi(&ptr[1]);
  169.       goto skip;
  170.    }
  171.    switch (ptr[1]) {
  172.    case '!':
  173.       break;
  174.    case '-':
  175.       num += atoi(&ptr[2]);
  176.       break;
  177.    default:
  178.       mode = HM_STR;
  179.       str  = ptr + 1;
  180.       break;
  181.    }
  182. skip:
  183.    switch (mode) {
  184.    case HM_STR:
  185.       len = strlen(str);
  186.       for (hist = H_head; hist; hist = hist->next) {
  187.          if (strncmp(hist->line, str, len) == 0 && *hist->line != '!') {
  188.             result = hist->line;
  189.             break;
  190.          }
  191.       }
  192.       break;
  193.    case HM_REL:
  194.       for (hist = H_head; hist && num--; hist = hist->next);
  195.       if (hist)
  196.          result = hist->line;
  197.       break;
  198.    case HM_ABS:
  199.       len = H_tail_base;
  200.       for (hist = H_tail; hist && len != num; hist = hist->prev, ++len);
  201.       if (hist)
  202.          result = hist->line;
  203.       break;
  204.    }
  205.    if (result) {
  206.       fprintf(stderr,"%s\n",result);
  207.       return(result);
  208.    }
  209.    printf("History failed\n");
  210.    return ("");
  211. }
  212.  
  213. replace_head(str)
  214. char *str;
  215. {
  216.    if (str == NULL)
  217.       str = "";
  218.    if (H_head) {
  219.       free (H_head->line);
  220.       H_head->line = malloc (strlen(str)+1);
  221.       strcpy (H_head->line, str);
  222.    }
  223. }
  224.  
  225.  
  226. pError(str)
  227. char *str;
  228. {
  229.    int ierr = (long)IoErr();
  230.    ierror(str, ierr);
  231. }
  232.  
  233. ierror(str, err)
  234. register char *str;
  235. {
  236.    register struct PERROR *per = Perror;
  237.  
  238.    if (err) {
  239.       for (; per->errstr; ++per) {
  240.          if (per->errnum == err) {
  241.             fprintf (stderr, "%s%s%s\n",
  242.                   per->errstr,
  243.                   (str) ? ": " : "",
  244.                   (str) ? str : "");
  245.             return ((short)err);
  246.          }
  247.       }
  248.       fprintf (stderr, "Unknown DOS error %d %s\n", err, (str) ? str : "");
  249.    }
  250.    return ((short)err);
  251. }
  252.  
  253. /*
  254.  * Disk directory routines
  255.  *
  256.  * dptr = dopen(name, stat)
  257.  *    struct DPTR *dptr;
  258.  *    char *name;
  259.  *    int *stat;
  260.  *
  261.  * dnext(dptr, name, stat)
  262.  *    struct DPTR *dptr;
  263.  *    char **name;
  264.  *    int  *stat;
  265.  *
  266.  * dclose(dptr)                  -may be called with NULL without harm
  267.  *
  268.  * dopen() returns a struct DPTR, or NULL if the given file does not
  269.  * exist.  stat will be set to 1 if the file is a directory.  If the
  270.  * name is "", then the current directory is openned.
  271.  *
  272.  * dnext() returns 1 until there are no more entries.  The **name and
  273.  * *stat are set.  *stat = 1 if the file is a directory.
  274.  *
  275.  * dclose() closes a directory channel.
  276.  *
  277.  */
  278.  
  279. struct DPTR *
  280. dopen(name, stat)
  281. char *name;
  282. int *stat;
  283. {
  284.    struct DPTR *dp;
  285.  
  286.    *stat = 0;
  287.    dp = (struct DPTR *)malloc(sizeof(struct DPTR));
  288.    if (*name == '\0')
  289.       dp->lock = DupLock(Myprocess->pr_CurrentDir);
  290.    else
  291.       dp->lock = Lock (name,ACCESS_READ);
  292.    if (dp->lock == NULL) {
  293.       free (dp);
  294.       return (NULL);
  295.    }
  296.    dp->fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  297.    if (!Examine (dp->lock, dp->fib)) {
  298.       pError (name);
  299.       dclose (dp);
  300.       return (NULL);
  301.    }
  302.    if (dp->fib->fib_DirEntryType >= 0)
  303.       *stat = 1;
  304.    return (dp);
  305. }
  306.  
  307. dnext(dp, pname, stat)
  308. struct DPTR *dp;
  309. char **pname;
  310. int *stat;
  311. {
  312.    if (dp == NULL)
  313.       return (0);
  314.    if (ExNext (dp->lock, dp->fib)) {
  315.       *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
  316.       *pname = dp->fib->fib_FileName;
  317.       return (1);
  318.    }
  319.    return (0);
  320. }
  321.  
  322.  
  323. dclose(dp)
  324. struct DPTR *dp;
  325. {
  326.    if (dp == NULL)
  327.       return (1);
  328.    if (dp->fib)
  329.       FreeMem (dp->fib,(long)sizeof(*dp->fib));
  330.    if (dp->lock)
  331.       UnLock (dp->lock);
  332.    free (dp);
  333.    return (1);
  334. }
  335.  
  336.  
  337. isdir(file)
  338. char *file;
  339. {
  340.    register struct DPTR *dp;
  341.    int stat;
  342.  
  343.    stat = 0;
  344.    if (dp = dopen (file, &stat))
  345.       dclose(dp);
  346.    return (stat == 1);
  347. }
  348.  
  349.  
  350. free_expand(av)
  351. register char **av;
  352. {
  353.    char **base = av;
  354.  
  355.    if (av) {
  356.       while (*av) {
  357.          free (*av);
  358.          ++av;
  359.       }
  360.       free (base);
  361.    }
  362. }
  363.  
  364. /*
  365.  * EXPAND(base,pac)
  366.  *    base           - char * (example: "df0:*.c")
  367.  *    pac            - int  *  will be set to # of arguments.
  368.  *
  369.  * 22-May-87 SJD.  Heavily modified to allow recursive wild carding and
  370.  *                 simple directory/file lookups. Returns a pointer to
  371.  *                 an array of pointers that contains the full file spec
  372.  *                 eg. 'df0:c/sear*' would result in : 'df0:C/Search'
  373.  *
  374.  *                 Now no longer necessary to Examine the files a second time
  375.  *                 in do_dir since expand will return the full file info
  376.  *                 appended to the file name. Set by formatfile().
  377.  *                 eg. fullfilename'\0'rwed  NNNNNN NNNN  DD-MMM-YY HH:MM:SS
  378.  *
  379.  *                 Caller must call free_expand when done with the array.
  380.  *
  381.  * base             bname =       ename =
  382.  * ------           -------       -------
  383.  *  "*"               ""            "*"
  384.  *  "!*.info"         ""            "*.info" (wild_exclude set)
  385.  *  "su*d/*"          ""            "*"      (tail set)
  386.  *  "file.*"          ""            "file.*"
  387.  *  "df0:c/*"         "df0:c"       "*"
  388.  *  ""                ""            "*"
  389.  *  "df0:.../*"       "df0:"        "*"      (recur set)
  390.  *  "df0:sub/.../*"   "df0:sub"     "*"      (recur set)
  391.  *
  392.  * ---the above base would be provided by execom.c or do_dir().
  393.  * ---the below base would only be called from do_dir().
  394.  *
  395.  *  "file.c"          "file.c"      ""       if (dp == 0) fail else get file.c
  396.  *  "df0:"            "df0:"        "*"
  397.  *  "file/file"       "file/file"   ""       (dp == 0) so fail
  398.  *  "df0:.../"        "df0:"        "*"      (recur set)
  399.  *
  400.  */
  401.  
  402.  
  403. char **
  404. expand(base, pac)
  405. char *base;
  406. int *pac;
  407. {
  408.    register char *ptr;
  409.    char **eav = (char **)malloc(sizeof(char *) * (2));
  410.    short eleft, eac;
  411.    char *name;
  412.    char *svfile();
  413.    char *bname, *ename, *tail;
  414.    int stat, recur, scr, bl;
  415.    register struct DPTR *dp;
  416.  
  417.    *pac = recur = eleft = eac = 0;
  418.  
  419.    base = strcpy(malloc(strlen(base)+1), base);
  420.    for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
  421.  
  422.    if (!*ptr)   /* no wild cards */
  423.       --ptr;
  424.    else
  425.       for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
  426.  
  427.    if (ptr < base) {
  428.       bname = strcpy (malloc(1), "");
  429.    } else {
  430.       scr = ptr[1];
  431.       ptr[1] = '\0';
  432.       if (!strcmp(ptr-3,".../")) {
  433.          recur = 1;
  434.          *(ptr-3) = '\0';
  435.       }
  436.       bname = strcpy (malloc(strlen(base)+2), base);
  437.       ptr[1] = scr;
  438.    }
  439.    bl = strlen(bname);
  440.    ename = ++ptr;
  441.    for (; *ptr && *ptr != '/'; ++ptr);
  442.    scr = *ptr;
  443.    *ptr = '\0';
  444.    if (scr) ++ptr;
  445.    tail = ptr;
  446.  
  447.    if ((dp = dopen (bname, &stat)) == NULL || (stat == 0 && *ename)) {
  448.       free (bname);
  449.       free (base);
  450.       free (eav);
  451.       return (NULL);
  452.    }
  453.  
  454.    if (!stat) {                /* eg. 'dir file' */
  455.       char *p,*s;
  456.       for(s = p = bname; *p; ++p) if (*p == '/' || *p == ':') s = p;
  457.       if (s != bname) ++s;
  458.       *s ='\0';
  459.       eav[eac++] = svfile(bname,dp->fib->fib_FileName,dp->fib);
  460.       goto done;
  461.    }
  462.    if (!*ename) ename = "*";    /* eg. dir df0: */
  463.    if (*bname && bname[bl-1] != ':' && bname[bl-1] != '/') { /* dir df0:c */
  464.       bname[bl] = '/';
  465.       bname[++bl] = '\0';
  466.    }
  467.    while ((dnext (dp, &name, &stat)) && !breakcheck()) {
  468.         int match = compare_ok(ename,name);
  469.       if (match && !(!recur && *tail)) {
  470.          if (eleft < 2) {
  471.                char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
  472.                movmem (eav, scrav, (eac + 1) << 2);
  473.                free (eav);
  474.                eav = scrav;
  475.                eleft = 10;
  476.          }
  477.          eav[eac++] = svfile(bname,name,dp->fib);
  478.          --eleft;
  479.       }
  480.       if ((*tail && match) || recur) {
  481.          int alt_ac;
  482.          char *search, **alt_av, **scrav;
  483.          BPTR lock;
  484.  
  485.          if (!stat)           /* expect more dirs, but this not a dir */
  486.             continue;
  487.          lock = CurrentDir (dp->lock);
  488.          search = malloc(strlen(ename)+strlen(name)+strlen(tail)+5);
  489.          strcpy (search, name);
  490.          strcat (search, "/");
  491.          if (recur) {
  492.             strcat(search, ".../");
  493.             strcat(search, ename);
  494.          }
  495.          strcat (search, tail);
  496.          scrav = alt_av = expand (search, &alt_ac);
  497.          /* free(search); */
  498.          CurrentDir (lock);
  499.          if (scrav) {
  500.             while (*scrav) {
  501.                int l;
  502.                if (eleft < 2) {
  503.                   char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
  504.                   movmem (eav, scrav, (eac + 1) << 2);
  505.                   free (eav);
  506.                   eav = scrav;
  507.                   eleft = 10;
  508.                }
  509.  
  510.                l = strlen(*scrav);
  511.                scrav[0][l] = ' ';
  512.                eav[eac] = malloc(bl+l+45);
  513.                strcpy(eav[eac], bname);
  514.                strcat(eav[eac], *scrav);
  515.                eav[eac][l+bl] = '\0';
  516.  
  517.                free (*scrav);
  518.                ++scrav;
  519.                --eleft, ++eac;
  520.             }
  521.             free (alt_av);
  522.          }
  523.       }
  524.    }
  525. done:
  526.    dclose (dp);
  527.    *pac = eac;
  528.    eav[eac] = NULL;
  529.    free (bname);
  530.    free (base);
  531.    if (eac) {
  532.       return (eav);
  533.    }
  534.    free (eav);
  535.    return (NULL);
  536. }
  537.  
  538. /*
  539.  * Compare a wild card name with a normal name
  540.  */
  541.  
  542. #define MAXB   8
  543.  
  544. compare_ok(wild, name)
  545. char *wild, *name;
  546. {
  547. register char *w = wild;
  548. register char *n = name;
  549. char *back0[MAXB], *back1[MAXB];
  550. int bi=0, queryflag;
  551.  
  552. if (*w=='!') return !compare_ok(wild+1,name);
  553. if (queryflag=(*w=='&')) w++;
  554. while (*n || *w) {
  555.    switch (*w) {
  556.       case '*':
  557.        if (bi==MAXB) { printf(stderr,"Too many levels of '*'\n"); return 0; }
  558.        back0[bi] = w;
  559.        back1[bi] = n;
  560.        ++bi;
  561.        ++w;
  562.        continue;
  563. goback:
  564.        --bi;
  565.        while (bi >= 0 && *back1[bi] == '\0') --bi;
  566.        if (bi < 0) return 0;
  567.        w = back0[bi] + 1;
  568.        n = ++back1[bi];
  569.        ++bi;
  570.        continue;
  571.       case '?':
  572.        if (!*n) goto goback;
  573.        break;
  574.       default:
  575.        if (Toupper(*n)!=Toupper(*w)) goto goback;
  576.        break;
  577.       }
  578.    if (*n) ++n;
  579.    if (*w) ++w;
  580.    }
  581. if (queryflag) {
  582.     char in[256];
  583.     printf("Select \23337m%-16s\2330m [y/n] ? ",name);
  584.     gets(in);
  585.     return (Toupper(*in)=='Y');
  586.     }
  587. return 1;
  588. }
  589.  
  590. char *svfile(s1,s2,fib)
  591. char *s1,*s2;
  592. FIB *fib;
  593. {
  594. char *p = malloc (strlen(s1)+strlen(s2)+45);
  595. strcpy(p, s1);
  596. strcat(p, s2);
  597. formatfile(p,fib);
  598. return p;
  599. }
  600.  
  601. /* will have either of these formats:
  602.  *
  603.  *    fullfilename'\0'hsparwed   <Dir>       DD-MMM-YY HH:MM:SS\n'\0'
  604.  *    fullfilename'\0'hsparwed  NNNNNN NNNN  DD-MMM-YY HH:MM:SS\n'\0'
  605.  *                              1111111111222222222233333333334 4  4
  606.  *                    01234567890123456789012345678901234567890 1  2
  607.  */
  608. formatfile(str,fib)
  609. char *str;
  610. FIB *fib;
  611. {
  612. char *dates();
  613. int i;
  614. while(*str++);
  615. for (i=7; i>=0; i--)
  616.     *str++ = ((fib->fib_Protection & (1L<<i)) ? "hspa----" : "----rwed")[7-i];
  617. if (fib->fib_DirEntryType < 0)
  618.   sprintf(str,"  %6ld %4ld  ", (long)fib->fib_Size, (long)fib->fib_NumBlocks);
  619. else strcpy(str,"   <Dir>       ");
  620. strcat(str,dates(&fib->fib_Date));
  621. }
  622.  
  623. /* Sort routines */
  624.  
  625. long cmp(s1, s2)
  626. char **s1, **s2;
  627. {
  628. return (long)Strcmp(*s1, *s2);
  629. }
  630.  
  631. Cmp() {
  632. #asm
  633.     public    _geta4
  634.     movem.l    d2-d3/a4/a6,-(sp)
  635.     movem.l    a0/a1,-(sp)
  636.     bsr    _geta4
  637.     bsr    _cmp
  638.     addq.l    #8,sp
  639.     movem.l    (sp)+,d2-d3/a4/a6
  640. #endasm
  641. }
  642.  
  643. QuickSort(av, n)
  644. char *av[];
  645. int n;
  646. {
  647. QSort(av, (long)n, 4L, Cmp);
  648. }
  649. SHAR_EOF
  650. cat << \SHAR_EOF > shell.doc
  651.  
  652.         INSTRUCTIONS FOR SHELL Version: 3.02A 20-Dec-88
  653.         ===============================================
  654.  
  655.   Contents
  656.   --------
  657.  
  658.     O.    Changes over old versions
  659.     I.    Description
  660.     II.   Overview of Major features
  661.     III.  Restrictions
  662.     IV.   PIPES
  663.     V.    Command Pre-processor
  664.     VI.   Command Line Editing
  665.     VII.  Function Keys
  666.     VIII. Shell Commands
  667.     IX.   Special Set Variables
  668.     X.    Advanced Topics
  669.     XI.   Example login file
  670.     XII.  Example script file
  671.     XIII. Default values
  672.     XIV.  Why ARP ?
  673.  
  674. O.  Changes over old version
  675.     ------------------------
  676.  
  677. New to 3.02A:
  678.  
  679. - New commands: fornum, forline, strleft, strright, strmid, strlen, exec.
  680. - Improved commands: foreach, pri.
  681. - New system variable _clinumber.
  682. - You can now split long lines in source files (see source for details).
  683. - window -q now lists also position of screens/windows, not only dimension.
  684. - Since strings are handled directly from Shell with new commands,
  685.   rpn is now used only for calculations; string commands are gone.
  686.   However, now RPN is really usable.
  687. - Changed rawgets() to fix some problems with function keys, multi-line
  688.   editing and window resizing; also, fixed bug with ^E.
  689. - cat now warns you if it can't find any file matching your pattern.
  690. - Now uses DOS packets to get ptr to CLI window; this fixes a bug that
  691.   caused problems if Shell was run on unactive windows.
  692. - Fixed minor bugs (htype printed some more ASCII bytes, some commands
  693.   returned random values, history didn't print CR's).
  694. - Heavy mods to this file.
  695.  
  696. New to 3.01A:
  697.  
  698. - Fixed bug with strings: before it printed strings with lenght 1 more
  699.   than specified lenght.
  700. - Made some additions and corrected many errors in Shell.doc (this file).
  701. - Modified handler of external commands to allow things like DATE "?"
  702.   (always use quotes).
  703. - Corrected cat: it didn't work with STDIN before.
  704.  
  705. I.  Description
  706.     -----------
  707.  
  708. This version of Shell is the follow of:
  709.     Shell V2.04 (C)Copyright 1986, Matthew Dillon, All Rights Reserved
  710.     Shell V2.04M-V2.07M by Steve Drew
  711.     Shell V2.08MI and V3.xxA by Carlo Borreo & Cesare Dieni
  712.  
  713. Send suggestions/criticism/anything else to Carlo Borreo or Cesare Dieni at:
  714.  
  715.     BITNET:  PERUGIA@ICNUCEVM.BITNET    
  716.  
  717. or
  718.     Carlo Borreo        Cesare Dieni
  719.     Via G. Berio 34        Via G. Taddei 3
  720.     I-18100 Imperia        I-56100 Pisa
  721.     Italy            Italy
  722.  
  723. For older version: Steve Drew at:
  724.  
  725.         ENET:    CGFSV1::DREW
  726.         ARPA:    drew%cfgsv1.dec.com@decwrl.dec.com
  727.         USENET:  {decvax|decwrl}!cgfsv1.dec.com!drew
  728.  
  729. or
  730.         52 Castledale Cres N.E.
  731.         Calgary, Alberta
  732.         Canada
  733.  
  734. You may distribute this program for non-profit only.
  735.  
  736.  
  737. II. OVERVIEW
  738.     --------
  739.  
  740. Shell provides a convient AmigaDos alternative command interface.
  741. All its commands are internal and thus does not rely on the c:
  742. commands for any functionality.
  743.  
  744. Major features include:
  745.  
  746.     -command line editing
  747.     -shell & Amigados search path support
  748.     -simple history
  749.     -redirection of any command
  750.     -piping
  751.     -aliases
  752.     -variables & variable handling (embedded variables)
  753.     -file name expansion via conventional wild carding ('?', '*' and more)
  754.     -conditionals (if/else ect..)
  755.     -source files  (w/ gotos and labels)
  756.     -many built in commands to speed things up
  757.  
  758.  
  759. III. RESTRICTIONS
  760.      ------------
  761.  
  762.     o AmigaDos execute command will not work. Alternative is to use shell
  763.       own script language (which is more powerful) or to do a 'run execute'.
  764.     o This version runs UNDER WORKBENCH 1.2 or 1.3.
  765.     o VDK handler has a bug with setting file dates so when using the copy
  766.       command and VDK you should use the -d switch otherwise your file date
  767.       in vdk: will be bad. (This is not a bug with shell)
  768.     o If using with conman it may be best to start shell with the -a switch
  769.       (shell -a .login) to turn off shell's command line editing and use
  770.       conmans instead.
  771.  
  772.  
  773. IV. NOTES ON PIPES
  774.     --------------
  775.  
  776.     PIPES have been implimented using temporary RAM: files.  Thus, you
  777.     should be careful when specifying a 'ram:*' expansion as it might
  778.     include the temp. files.  These files are deleted on completion of
  779.     the pipe segment.
  780.  
  781.     The file names used are completely unique, even with multiple shell
  782.     running simultaniously.
  783.  
  784.     My favorite new feature is the fact that you can now redirect to and
  785.     from, and pipe internal commands.  'echo charlie >ram:x', for
  786.     instance.  Another favorite:
  787.  
  788.        echo "echo mem | shell" | shell
  789.  
  790.     To accomplish these new features, I completely re-wrote the command
  791.     parser in execom.c
  792.  
  793.     NO BCPL program should be output-append redirected (>>).
  794.  
  795.  
  796. V.  COMMAND PRE-PROCESSOR
  797.     ---------------------
  798.  
  799.     Preprocessing is done on the command line before it is passed on to
  800.     an internal or external routine:
  801.  
  802.     ^c    where c is a character is converted to that control character.
  803.         Thus, say '^l' for control-l.
  804.  
  805.     $name    where name is a variable name.  Variable names can consist of
  806.         0-9, a-z, A-Z, and underscore (_).  The contents of the
  807.         specified variable is used.  If the variable doesn't exist,
  808.         the specifier is used.  That is, if the variable 'i' contains
  809.         'charlie', then '$i' -> 'charlie'.  If the variable 'i' doesn't
  810.         exist, then '$i'->'$i' .
  811.  
  812.     ;    delimits commands.   echo charlie ; echo ben.
  813.  
  814.     ' '    (a space). Spaces delimit arguments.
  815.  
  816.     "string" a quoted string.  For instance, if you want to echo five spaces
  817.         and an 'a':
  818.  
  819.         echo      a       -> a
  820.         echo "    a"      ->      a
  821.  
  822.     \c    overide the meaning of special characters.  '\^a' is a
  823.         circumflex and an a rather than control-a.  To get a backslash,
  824.         you must say '\\'.
  825.  
  826.         also used to overide alias searching for commands.
  827.  
  828.     >file    specify output redirection.  All output from the command is
  829.         placed in the specified file.
  830.  
  831.     >>file    specify append redirection (Does not work with BCPL programs).
  832.  
  833.     <file    specify input redirection. The command takes input from the
  834.         file rather than the keyboard (note: not all commands require
  835.         input; it makes no sense to say 'echo <charlie' since
  836.         the 'echo' command only outputs its arguments).
  837.  
  838.     |    PIPE specifier.  The output from the command on the left becomes
  839.         the input to the command on the right.  The current SHELL
  840.         implimentation uses temporary files to store the data.
  841.  
  842.     !!    execute the previously executed command.
  843.     !nn    (nn is a number).  Insert the history command numbered n (see
  844.         the HISTORY command)
  845.     !partial search backwards through the history list for a command which
  846.         looks the same as 'partial', and execute it.
  847.  
  848.     #    Enter comment.  The rest of the line is discarded (note: \#
  849.         will, of course, overide the comment character's special
  850.         meaning)
  851.  
  852.  
  853. VI. COMMAND LINE EDITING
  854.     --------------------
  855.  
  856.     o Command line can be upto 255 chars.
  857.     o Inserts and deletes are handled correctly over multiple screen lines.
  858.     o Shell will keep track of the line width should the window get resized.
  859.  
  860.     KEY DEFINITIONS:
  861.         Up Arrow    Recal previous commands
  862.         Down Arrow  Recal commands
  863.         Left Arrow  Move cursor about command line.
  864.         Right Arrow  "     "      "      "      "
  865.         Shift-Up Arrow    Get start of history
  866.         Shift-Down Arrow   "  end   "     "
  867.         Shift-Left Arrow  Moves cursor a bit left
  868.         Shift-Right Arrow   "     "    "  "  right
  869.         ^A        Toggle insert/overtype mode.
  870.         ^D        EOF
  871.         ^E        Put cursor at end of text.
  872.         ^K        Delete to end of line.
  873.         ^R        Retype current line.
  874.         ^U        Erase entire line.
  875.         ^X        Erase entire line.
  876.         ^Z        Put cursor at start of text.
  877.         f1 - f10    Execute command if variable exists.
  878.         F1 - F10    More commands (Shifted f keys).
  879.         Help        Invokes help command
  880.  
  881.  
  882. VII. FUNCTION KEYS
  883.      -------------
  884.  
  885.     Function keys now insert text to the current position on the command
  886.     line. They maybe terminated with a ^M (return). f1 would be non shifted
  887.     where as F1 is shifted.
  888.     Most of functions key have a default definition, but it may be changed.
  889.  
  890.       $ set f1 dir df0:^M
  891.  
  892.     will add the text 'dir df0:<return>' to the current line.
  893.  
  894.       $ set f1 dir
  895.  
  896.     would only add 'dir' you could then enter ' df0:<return>'
  897.  
  898.  
  899. VIII. SHELL COMMANDS
  900.       ---------------
  901.  
  902.    First to start shell from a CLI
  903.  
  904.    shell [-a] [-c command;command]
  905.  
  906.    where:
  907.     -a disables all command line editing features. This is useful for
  908.     when running shell over AUX:, and necessary if you are running
  909.     CONMAN.
  910.  
  911.     -c allows execution of one command line and then exits out of shell.
  912.     This is useful for running a internal shell commands in the
  913.     background or from an external application. eg:
  914.  
  915.         Run shell -c dir df0:; copy -r df0: df1: >nil:; echo "Done"
  916.  
  917.     If you 'Run' shell in the background without the -c switch shell
  918.     will detect this and imediatley exit.
  919.  
  920.    Command execution:
  921.  
  922.    Internal shell commands maybe abreviated.
  923.  
  924.    The first argument is the command-name... here is (in order) how Shell
  925.    tries to execute it:
  926.  
  927.     1) Alias list is searched for an alias exactly matching name.
  928.     2) Internal commands list is scanned for a command even partially
  929.        matching name (so you can, for instance, say resi for resident;
  930.        however, you should specify enough of a command to be unique).
  931.     3) ARP resident list is scanned (you can use Shell's resident
  932.        command to add/remove a file in this list).
  933.     4) At this point, command is supposed to be external (disk), and
  934.        is searched before in current directory, then in Shell's
  935.        path, and finally in AmigaDOS path.
  936.     5) As a last chance, AUTOMATIC SOURCING is tried.
  937.  
  938.    AUTOMATIC SOURCING may be accomplished by naming shell scripts with a
  939.    .sh suffix.  Thus, if you say 'stuff' and the file 'stuff.sh' exists in
  940.    your current or C: directory or anywhere in Shell search path, it will
  941.    be SOURCED with any arguments you have placed in the $_passed variable.
  942.    This is equivalent to typing 'source stuff.sh'
  943.  
  944.    Wild card expansions:
  945.     Most shell commands will accept multiple arguments that can
  946.     be as a result of wild card expansion. Also when the calling
  947.     an external command shell will first expand any wild cards
  948.     to seperate arguments. If you wish to have the external command
  949.     handle it's own wild carding you will need to insert quotes
  950.     around the special wild card characters ? and *.
  951.  
  952.     eg.
  953.         arc a new.arc *.txt    - shell will expand and pass to arc
  954.         arc a new.arc "*.txt"    - let arc expand the wild cards.
  955.  
  956.     Wild card expansions:
  957.  
  958.     ?    match any single character
  959.     *    match any string
  960.     .../*    recursive search down ALL sub directories from current level
  961.     !    Exclude pattern matching specifier
  962.     &    prefixed to patterns, ask confirmation for each file
  963.  
  964.     Examples:
  965.  
  966.     df0:.../*        all files in all directories on df0:
  967.     df0:.../!*.info     full directory tree of df0: but exclude
  968.                 any ugly .info files.
  969.     !*.o !*.c        will result in ALL files matching since what
  970.                 doesn't match the !*.o will match the !*.c
  971.     df1:&*            all files in root of df1:, but ask 
  972.                 confirmation for each
  973.  
  974.     LIST OF COMMANDS:
  975.     -----------------
  976.  
  977.     ABORTLINE
  978.     Usage    : abortline
  979.     Example    : echo a;abort;echo b
  980.     Results    : a
  981.  
  982.     Causes the rest of the line to be aborted. Intended for use in
  983.     conjunction with exception handling.
  984.  
  985.     ADDBUFFERS
  986.     Usage    : addbuffers drive buffers
  987.     Example    : addbuffers df0: 24
  988.  
  989.     Just like AmigaDOS addbuffer command, causes new buffers to be
  990.     allocated for disk I/O. Each buffer costs 512 bytes of CHIP memory.
  991.  
  992.     ALIAS
  993.     Usage    : alias [name [command string] ]
  994.     Example    : alias vt "echo Starting VT100;run sys:tools/vt100"
  995.  
  996.     Sets a name to be a string. You can alias a single name to a set
  997.     of commands if you enclose them in quotes as above. By simply
  998.     typing vt, the command line above would be executed.
  999.  
  1000.     Argument Passing to an Alias:
  1001.  
  1002.     Usage    : alias name "%var [command string]"
  1003.     Example    : alias xx "%q echo hi $q, how are ya."
  1004.           xx Steve
  1005.     Results    : hi Steve, how are ya.
  1006.  
  1007.     The second form of the alias command allows passing of arguments
  1008.     to any position within the command string via use of a variable
  1009.     name. To pass arguments to the end of a command string this method
  1010.     is actually not necessary.
  1011.  
  1012.     Typing "alias name" you will get the alias for that name, while with
  1013.     "alias" you get a list of all alias.
  1014.  
  1015.     ASET
  1016.     Usage    : aset name value
  1017.     Example    : aset INCLUDE include:
  1018.  
  1019.     Set a variable in a way that is compatible with Aztec SET command;
  1020.     this is completely different from Shell variable.
  1021.     May even be used to set ARP variables.
  1022.  
  1023.     ASSIGN
  1024.     Usage    : assign [logical [physical] ]
  1025.     Example    : assign C: df1:c
  1026.  
  1027.     Use it like AmigaDOS assign command to set, remove or list
  1028.     assignments of logical names to directories.
  1029.  
  1030.     CAT
  1031.     Usage    : cat [-n][file file....]
  1032.     Example    : cat foo.txt
  1033.  
  1034.     Type the specified files onto the screen.  If no file is specified,
  1035.     STDIN in used.  CAT is meant to output text files only.
  1036.     Specifying -n option you will get numbered lines.
  1037.  
  1038.     CD
  1039.     Usage    : cd [path]
  1040.     Example    : cd df0:devs/printers
  1041.  
  1042.     Change your current working directory.  You may specify '..' to go
  1043.     back one directory (this is a CD specific feature, and does not
  1044.     work with normal path specifications).
  1045.  
  1046.     CD without any arguments displays the path of the directory you
  1047.     are currently in.
  1048.  
  1049.     CLOSE
  1050.     Usage    : close filenumber
  1051.  
  1052.     Close the specified file opened by open.
  1053.     See open and flist for more info.
  1054.  
  1055.     COPY
  1056.     (CP)
  1057.     Usage    : copy [-u][-d] file file
  1058.     or    : copy [-u][-d] file1 file2...fileN dir
  1059.     or    : copy [-r][-u][-d] dir1 dir2...dirN dir
  1060.     options    :
  1061.         -r    recursive, copy all subdirectories as well.
  1062.         -u    update, if newer version exist on dest, don't copy
  1063.         -d    don't set destination file date to that of source.
  1064.  
  1065.     Example    : copy -r df0: df1:
  1066.  
  1067.     Copy files or directories. When copying directories, the -r option
  1068.     must be specified to copy subdirectories as well.  Otherwise, only
  1069.     top level files in the source directory are copied.
  1070.  
  1071.     All files will be displayed as they are copied and directory's
  1072.     displayed as they are created. This output can be suppessed by
  1073.     redirecting to nil: eg. copy -r >nil: df0: df1:
  1074.  
  1075.     Copy will abort after current file on Control-C.
  1076.  
  1077.     Copy by default sets the date of the destination file to that of
  1078.     the source file. To overide this feature use the -d switch.
  1079.  
  1080.     Another useful option is the -u (update) mode were copy will not
  1081.     copy any files which exists already in the destination directory
  1082.     if the destination file is newer or equal to the source file.
  1083.     This is useful when developing code say in ram: eg. 'copy *.c ram:'
  1084.     when done you can copy -u ram: df1: and only those modules you have
  1085.     modified will be copied back.
  1086.  
  1087.     Copy command will now create the destination directory if it does
  1088.     not exist when specified as 'copy [-r] dir dir'. If you specify
  1089.     copy file file file dir, then 'dir' must already exist.
  1090.  
  1091.     CP
  1092.     Equivalent to copy.
  1093.  
  1094.     DATE
  1095.     Usage    : date [new date and/or time]
  1096.     Example    : date Wednesday  # this refers to NEXT wed, of course
  1097.  
  1098.     Used to read or set system date and/or time. All standard options
  1099.     may be used (yesterday, tomorrow, monday, etc.).
  1100.     Leading zero's are not necessary.
  1101.     Without parameters shows Dddddd DD-MMM-YY HH:MM:SS.
  1102.  
  1103.     DEC
  1104.     Usage    : dec varname [value]
  1105.     Example    : dec abc
  1106.  
  1107.     Decrement the numerical equivalent of the variable with specified
  1108.     value (default: 1) and place the ASCII-string result back into
  1109.     that variable.
  1110.  
  1111.     DELETE
  1112.     (RM)
  1113.     Usage    : delete [-p][-r] file file file...
  1114.     Example    : delete foo.txt test.c
  1115.  
  1116.     Remove (delete) the specified files.  Remove always returns
  1117.     errorcode 0.  You can remove empty directories.  The '-r' option
  1118.     will remove non-empty directories by recursively removing all sub
  1119.     directories.
  1120.     You can remove delete-protected files specifying -p option.
  1121.     If you specify any wildcard deletes the files will be listed as
  1122.     they are deleted. This can be suppressed by redirecting to nil:
  1123.  
  1124.     DIR
  1125.     (LS)
  1126.     Usage    : dir [-sdf] [path path ... ]
  1127.     Example    : dir df0:
  1128.     options    :
  1129.         -s  short multi(4) column display.
  1130.         -d  list directories only
  1131.         -f  list files only
  1132.  
  1133.     Displays a directory of specified files. Default output shows
  1134.     date, protection, block size, byte size and total space used.
  1135.     Protections flags include new 1.2/1.3 flags (see under protect).
  1136.     Files are alphabetically sorted, without case sensitivity, and
  1137.     directories are always in red pen.
  1138.  
  1139.     DISKCHANGE
  1140.     Usage    : diskchange drive
  1141.  
  1142.     Like AmigaDOS diskchange.
  1143.  
  1144.     ECHO
  1145.     Usage    : echo [-n] string
  1146.     Example    : echo hi there
  1147.     Results    : hi there
  1148.  
  1149.     Echo the string given. If -n switch given no newline is
  1150.     appended.
  1151.  
  1152.     ELSE ;
  1153.     Usage    : else ; command
  1154.     Usage    : if -f foo.c ; else ; echo "Not there" ; endif
  1155.  
  1156.     Else clause, must follow an IF statement.
  1157.  
  1158.     ENDIF
  1159.     Usage    : endif
  1160.  
  1161.     The end of an if statement.
  1162.  
  1163.     Note: if you return from a script file with unterminated IF's
  1164.     and the last IF was false, prompt will be changed to an
  1165.     underscore ('_') and no commands will be executed until
  1166.     'endif' is typed.
  1167.  
  1168.     EXEC
  1169.     Usage    : exec command
  1170.     Example    : set util SYS:sytem/utilities
  1171.           exec $util/make    # would not work without exec
  1172.  
  1173.     Execute the command specified; exec command is equivalent to
  1174.     command, only you can use variables to specify command name.
  1175.  
  1176.     FAULT
  1177.     Usage    : fault error1 .. errorN
  1178.     Example    : fault 205 212
  1179.  
  1180.     Like AmigaDOS fault, prints specified error messages.
  1181.  
  1182.     FILENOTE
  1183.     Usage: filenote file1 .. filen  note
  1184.  
  1185.     Set AMIGADOS comment of the specified file. This is not very useful,
  1186.     since in current implementation of Shell file comments are not listed
  1187.     in directory, but it was so easy to implement...
  1188.  
  1189.     FLIST
  1190.     Usage    : flist
  1191.  
  1192.     Lists the filenumbers of files opened by open.
  1193.     See open and close for more info.
  1194.  
  1195.     FOREACH
  1196.     Usage    : foreach [-v] varname ( strings ) command
  1197.     Example    : foreach i ( a b c d ) "echo -n $i;echo \" ha\""
  1198.     Result    : a ha
  1199.           b ha
  1200.           c ha
  1201.           d ha
  1202.  
  1203.     'strings' is broken up into arguments.  Each argument is placed in
  1204.     the variable 'varname' in turn and 'command' executed.  To execute
  1205.     multiple commands, place them in quotes.
  1206.  
  1207.     Foreach is especially useful when interpreting passed arguments in
  1208.     an alias.
  1209.  
  1210.     eg.
  1211.         foreach i ( *.pic ) viewilbm $i
  1212.     assuming a.pic and b.pic in current directory the following commands
  1213.     will occur:
  1214.         viewilbm a.pic
  1215.         viewilbm b.pic
  1216.  
  1217.     Flag -v causes arguments to be displayed every time command is
  1218.     executed.
  1219.  
  1220.     FOREVER
  1221.     Usage    : forever command
  1222.     or    : forever "command;command;command..."
  1223.  
  1224.     The specified commands are executed over and over again forever.
  1225.  
  1226.     -Execution stops if you hit ^C
  1227.     -If the commands return with an error code.
  1228.  
  1229.    FORLINE
  1230.     Usage    : forline var filename command
  1231.     or    : forline var filename "command;command..."
  1232.     Example    : forline i RAM:temp "echo line $_linenum=$i"
  1233.  
  1234.     For each ASCII line of file specified commands are executed and
  1235.     var points to line content. You can check system variable _linenum
  1236.     to find the number of the line currently read.
  1237.  
  1238.    FORNUM
  1239.     Usage    : fornum var n1 n2 command
  1240.     or    : fornum var n1 n2 "command;command..."
  1241.     Example    : fornum x 1 10 echo $1
  1242.  
  1243.     Executes command(s) for all numerical values of x between n1 and n2.
  1244.  
  1245.    GOTO
  1246.     Usage    : goto label
  1247.     Example    :
  1248.           label start
  1249.             echo "At start"
  1250.             dir ram:
  1251.             goto start
  1252.  
  1253.     Goto the specified label name.  You can only use this command from a
  1254.     source file. Labels may now be forward or reverse from current
  1255.     position.
  1256.  
  1257.     HELP
  1258.     Usage    : help
  1259.     Example    : help
  1260.  
  1261.     Simply displays all the available commands.  The commands are
  1262.     displayed in search-order.  That is, if you give a partial name
  1263.     the first command that matches that name in this list is the one
  1264.     executed.  Generally, you should specify enough of a command so that
  1265.     it is completely unique.
  1266.  
  1267.     HISTORY
  1268.     Usage    : history [partial_string]
  1269.     Example    : history
  1270.  
  1271.     Displays the enumerated history list.  The size of the list is
  1272.     controlled by the _history variable.  If you specify a partial-
  1273.     string, only those entries matching that string are displayed.
  1274.  
  1275.     HOWMANY
  1276.     Usage    : howmany
  1277.  
  1278.     This command tells you how many instances of Shell are running
  1279.     in your system.
  1280.  
  1281.     HTYPE
  1282.     Usage    : htype file1 .. filen
  1283.  
  1284.     Displays the specified files in hex and ASCII, just like the system
  1285.     command Type file opt h. Especially suitable for binary files.
  1286.  
  1287.     IF
  1288.     Usage    : if [-n] argument conditional argument ;
  1289.     or    : if [-n] argument
  1290.     or    : if [-n] -f file
  1291.     or    : if [-n] -d file/dir
  1292.     or    : if [-n] -m
  1293.     or    : if [-n] -t file file1 .. fileN
  1294.     or    : if [-n] -r rpnexpression
  1295.  
  1296.     If a single argument is something to another argument.  Conditional
  1297.     clauses allowed:
  1298.  
  1299.     <, >, =, and combinations (wire or).  Thus <> is not-equal, >=
  1300.     larger or equal, etc...
  1301.  
  1302.     If arguments are not numeric, they are compared as strings.
  1303.  
  1304.     Usually the argument is either a constant or a variable ($varname).
  1305.  
  1306.     The second form if IF is conditional on the existance of the argument.
  1307.     If the argument is a "" string, then false , else TRUE.
  1308.  
  1309.     The third form of IF used by -f switch checks for existance of
  1310.     the specified file.
  1311.  
  1312.     Switch -d tests the type of the object specified: if it is a
  1313.     directory, then TRUE; if it is a file (or it doesn't exist)
  1314.     then FALSE.
  1315.  
  1316.     Switch -m is used to test if FAST memory is present, i.e. wheter
  1317.     more than 512K RAM are available.
  1318.     Example (to be included in a login.sh file):
  1319.     if -m; resident -a as ln cc; endif
  1320.  
  1321.     Using -t form compares the date and time of the first file with
  1322.     all the others; if the first is younger than ALL the others, then
  1323.     FALSE, else TRUE. If a file doesn't exists, it is considered as
  1324.     being older.
  1325.     This feature is especially useful for building makefiles without
  1326.     using any MAKE utility.
  1327.     Example:
  1328.     if -t test.o test.asm test.i ; asm -o test.o test.asm ; endif
  1329.  
  1330.     Option -r evaluates a given RPN expression (see under RPN for more
  1331.     info): if value on top of stack is 0, then FALSE, else TRUE.
  1332.  
  1333.     Switch -n (NOT) reverses the result.
  1334.  
  1335.     When using 'IF' command interactively if you are entering commands
  1336.     following an 'IF' that was false, the prompt will be set to a
  1337.     underscore '_ ' to indicate all commands will be ignored until
  1338.     an 'ELSE' or 'ENDIF' command is seen.
  1339.  
  1340.     INC
  1341.     Usage    : inc varname [value]
  1342.     Example    : inc abc 5
  1343.  
  1344.     Increment the numerical equivalent of the variable with specified
  1345.     value (default: 1) and place the ascii-string result back into
  1346.     that variable.
  1347.  
  1348.     INFO
  1349.     Usage    : info
  1350.  
  1351.     Display Device statistics for all the disk-type devices in system
  1352.     (DFk:, HDk, JHk:, RAM:, RDk: ...), just like the system command
  1353.     info. Gives block used/free, % used, errs, status and volume name.
  1354.  
  1355.     INPUT
  1356.     Usage    : input var var ... var
  1357.     Example    : input abc
  1358.  
  1359.     Input from STDIN (or a redirection, or a pipe) to a variable.  The
  1360.     next input line is placed in the variable.
  1361.  
  1362.     JOIN
  1363.     Usage    : join [-r] file1..fileN destfile
  1364.     Example    : join part1 part2 part3 total
  1365.  
  1366.     Joins the specified files to get destfile. If destfile already
  1367.     exists, an error message is generated and operation is aborted,
  1368.     unless you specify -r (replace) option.
  1369.  
  1370.     LABEL
  1371.     Usage    : label name
  1372.  
  1373.     Create a program label right here. Used in source files, can then
  1374.     GOTO a label.
  1375.  
  1376.     LS
  1377.     Equivalent to dir.
  1378.  
  1379.     MD
  1380.     Equivalent to mkdir.
  1381.  
  1382.     MEM
  1383.     Usage    : mem
  1384.  
  1385.     Display current memory statistics for CHIP memory and
  1386.     FAST memory (if any installed).
  1387.  
  1388.     MKDIR
  1389.     (MD)
  1390.     Usage    : mkdir name name name...
  1391.     Example    : mkdir df0:stuff
  1392.  
  1393.     Create the specified directories.
  1394.  
  1395.     MV
  1396.     Equivalent to rename.
  1397.  
  1398.     OPEN
  1399.     Usage    : open filename filemode filenumber
  1400.     Example    : open RAM:data w 1
  1401.  
  1402.     This allows you to open a file, redirect to it as many commands
  1403.     as you like, then close it.
  1404.     Filename is any valid AmigaDOS filename, filemode is either r
  1405.     for read or w for write, filenumber is a number between 1 and 10.
  1406.     To redirect a program to or from an open file, use as your redir
  1407.     filename a dot followed by the filenumber.
  1408.     Here is a complete example:
  1409.  
  1410.         open RAM:data w 1
  1411.         echo -n 2+2= >.1
  1412.         rpn 2 2 + . CR >.1
  1413.         close 1
  1414.         type RAM:data    # will display 2+2=4
  1415.     See also close, flist.
  1416.  
  1417.     PATH
  1418.     Usage    : path
  1419.  
  1420.     Used to list AmigaDOS path. In current version can't be used to
  1421.     set it.
  1422.  
  1423.     PRI
  1424.     Usage    : pri clinumber pri
  1425.     Example    : pri 3 5    # set priority of cli #3 to 5
  1426.  
  1427.     Change the priority of the specified task (use PS command to
  1428.     determine clinumber). If you specify 0 as clinumber you can
  1429.     change priority of "this" task (the one executing shell).
  1430.  
  1431.     PROTECT
  1432.     Usage    : protect file1 ... filen [flags]
  1433.     Example    : protect myfile rwe
  1434.  
  1435.     Set AMIGADOS file protection flags for the file specified. Valid
  1436.     flags are h, s, p, a, r, w, e, d.
  1437.     If you don't specify the flags, all flags are cleared.
  1438.     Bit 'a' is new to WorkBench 1.2, while 'h', 's', 'p' are new to 1.3.
  1439.  
  1440.     PS
  1441.     Usage    : ps
  1442.  
  1443.     Gives status of DOS processes.  eg:
  1444.  
  1445.     Proc Command Name    CLI Type    Pri.  Address  Directory
  1446.      1   SHELL        Initial CLI   0      97b0  Stuff:shell
  1447.      2   sys:c/clockmem    Background  -10    2101a8  Workdisk:
  1448.      3   c:emacs        Background    0    212f58  Stuff:shell
  1449.      4   sys:c/VT100    Background    0    227328  Workdisk:
  1450.  
  1451.     Address is the addres of the task, directory is the process
  1452.     currently CD'd directory.
  1453.  
  1454.     PWD
  1455.     Usage    : pwd
  1456.  
  1457.     Rebuild _cwd by backtracing from your current directory.
  1458.  
  1459.     QUIT
  1460.     Usage    : quit
  1461.  
  1462.     Quit out of Shell back to CLI.
  1463.  
  1464.     RBACK
  1465.     Usage    : rback command
  1466.  
  1467.     Start a new process executing the specified command, but can't do
  1468.     input/output. Equivalent to 'run command >NIL: <NIL:'.
  1469.     This command is not fully reliable: use at your own risk.
  1470.  
  1471.     RENAME
  1472.     (MV)
  1473.     Usage    : rename from to
  1474.     or    : rename from from from ... from todir
  1475.  
  1476.     Allows you to rename a file or move it around within a disk.
  1477.     Allows you to move 1 or more files into a single directory.
  1478.  
  1479.     RESIDENT
  1480.     Usage    : resident [-a][-r] [files]
  1481.  
  1482.     This is ARP resident. Commands are searched by Shell in resident
  1483.     list BEFORE of searching on any external device.
  1484.     Option -a loads RESIDENT programs, -r removes them.
  1485.     Resident with no args lists resident programs.
  1486.     Not all programs can run as resident, see ARP docs for more info.
  1487.  
  1488.     RETURN
  1489.     Usage    : return [n]
  1490.     Example    : return 10
  1491.  
  1492.     Exit from a script file, or quit from shell with optional
  1493.     exit code.
  1494.  
  1495.     RM
  1496.     Equivalent to delete.
  1497.  
  1498.     RPN
  1499.     Usage    : rpn expression
  1500.     Example    : rpn 3 7 *    # Prints the value 21
  1501.  
  1502.     Evaluate an RPN expression, using 32-bit values. In older versions
  1503.     of Shell RPN contained string functions too, but now that strings
  1504.     are handled by specifical commands, these are no more needed.
  1505.     At end of evaluation, RPN prints values on stack, so you can
  1506.     say for instance "rpn $x 2 * | input x" to double the value of
  1507.     variable x.
  1508.     Functions implemented are:
  1509.  
  1510.         + - * /    Obvious meaning; / means integer division, of course
  1511.         %        Module operator e.g. "rpn 7 3 %" answers 1
  1512.         & | ~    Bitwise and, or, not operators
  1513.         > < ==    Tests for greater-than, lower-than, equal. To get
  1514.             a test for >= (or <=), you can use < ! (or > !)
  1515.         !        Logical not operator
  1516.         DUP        Duplicate value on top of stack
  1517.         DROP    Drop value on top of stack
  1518.         SWAP    Swap two values on top of stack
  1519.  
  1520.     RUN
  1521.     Usage    : run prgm args
  1522.     Example    : run emacs test.c
  1523.  
  1524.     Start a new process executing the specified command.
  1525.     In current implementation run command can't be redirected.
  1526.     This command is not fully reliable: use at your own risk.
  1527.     See also rback.
  1528.  
  1529.     SEARCH
  1530.     Usage    : search [-w][-c][-n][-r][-e][-q] filelist string
  1531.  
  1532.     Search specified files for a string. Only lines containing the
  1533.     specified strings are displayed.
  1534.  
  1535.     If you specify any directory in filelist, and use the -r (recurse)
  1536.     switch, all files in directory are recursively searched.
  1537.  
  1538.     Lines are numbered for default; use -n (number) switch to turn off
  1539.     line numbering.
  1540.  
  1541.     Search is normally not case sensitive; use -c (case) flag to turn ON
  1542.     case sensitivity.
  1543.  
  1544.     By specifying -e (exclude) switch, only lines NOT containing the
  1545.     specified string are listed.
  1546.  
  1547.     Using -w (wild) flag, only the lines matching with the string are
  1548.     listed.
  1549.     Notes to wild card matching;
  1550.     - Uses Shell standard matching.
  1551.     - Wild cards allowed are *, ?, !.
  1552.     - Matching is not case sensitive (even if you use -c flag).
  1553.     - The WHOLE line must match the string, not only a substring.
  1554.     - String MUST be enclosed in quotes to avoid wildcard expansion
  1555.  
  1556.     Flag -q (quiet) suppresses printing of file names.
  1557.  
  1558.     Examples:
  1559.         search -c -r df0:include ACCESS
  1560.     Find all occurrencies of ACCESS (in uppercase) in all files
  1561.     contained in include directory.
  1562.         search -w shell.h "#define*"
  1563.     Lists only lines of file beginning with (not simply containing)
  1564.     #define.
  1565.  
  1566.     SET
  1567.     Usage    : set [name] [string]
  1568.     Example    : set abc hello
  1569.  
  1570.     Set with no args lists all current variable settings.
  1571.     Set with one arg lists the setting for that particular variable.
  1572.     Specifying name and string, stores the string into variable name.
  1573.  
  1574.     Also See the section on special _variables.
  1575.  
  1576.  
  1577.     SLEEP
  1578.     Usage    : sleep timeout
  1579.     Example    : sleep 10
  1580.  
  1581.     Sleep for 'timeout' seconds, or until ^C typed.
  1582.  
  1583.     STACK
  1584.     Usage    : stack [number]
  1585.     Example    : stack 8000
  1586.  
  1587.     Changes the default stack for this CLI. Without arguments, prints
  1588.     it.
  1589.  
  1590.     STRHEAD
  1591.     Usage    : strhead varname breakchar string
  1592.     Example    : strhead j . foobar.bas
  1593.           echo $j
  1594.     Result    : foobar
  1595.  
  1596.     Remove everything after and including the breakchar in 'string' and
  1597.     place in variable 'varname'.
  1598.  
  1599.     STRINGS
  1600.     Usage    : strings file1..fileN minlenght
  1601.     Example    : strings c:dir c:list shell 7
  1602.  
  1603.     Prints strings contained in specified files (usually binary)
  1604.     with lenght >= minlenght.
  1605.  
  1606.     STRLEFT
  1607.     Usage    : strleft varname string n
  1608.     Example    : strleft x LongString 5    # Will set x to "LongS"
  1609.  
  1610.     Place leftmost n chars of string in variable varname.
  1611.  
  1612.     STRLEN
  1613.     Usage    : strlen varname string
  1614.     Example    : strlen x Hello    # Will set x to "5"
  1615.  
  1616.     Puts len of string in variable varname.
  1617.  
  1618.     STRMID
  1619.     Usage    : strmid varname string n1 [n2]
  1620.     Example    : strmid x LongString 5 3    # Will set x to "Str"
  1621.  
  1622.     Places n2 chars from string, starting at n1, in variable varname.
  1623.     By omitting n2, you get all chars from n1 to end of string.
  1624.  
  1625.     STRRIGHT
  1626.     Usage    : strright varname string n
  1627.     Example    : strright x LongString 5    # Will set x to "tring"
  1628.  
  1629.     Place rightmost n chars of string in variable varname.
  1630.  
  1631.     STRTAIL
  1632.     Usage    : strtail varname breakchar string
  1633.     Example    : strtail j . foobar.bas ; echo $j
  1634.     Result    : bas
  1635.  
  1636.     Remove everything before and including the breakchar in 'string' and
  1637.     place in variable 'varname'.
  1638.  
  1639.     SOURCE
  1640.     Usage    : source file [arguments]
  1641.     Example    : source mymake.sh all
  1642.     Result    : source file 'mymake.sh' called with var _passed = 'all'
  1643.  
  1644.     Execute commands from a file.  You can create SHELL programs in
  1645.     a file and then execute them with this command.  Source'd files
  1646.     have the added advantage that you can have loops in your command
  1647.     files (see GOTO and LABEL).  You can pass SOURCE files arguments
  1648.     by specifying arguments after the file name.  Arguments are passed
  1649.     via the _passed variable (as a single string).
  1650.  
  1651.     Long lines may be split by appending a backslash (\) at end of
  1652.     first half. However, even joined lines cannot be longer than
  1653.     ~255 chars. See example of source files.
  1654.  
  1655.     Automatic 'sourcing' is accomplished by placing a .sh extension on
  1656.     the file and executing it as you would a C program:
  1657.  
  1658.     --------- file hello.sh ---------
  1659.     foreach i ( $_passed ) "echo yo $i"
  1660.     ---------------------------------
  1661.  
  1662.     $ hello a b c
  1663.     yo a
  1664.     yo b
  1665.     yo c
  1666.  
  1667.     TYPE
  1668.     Equivalent to CAT.
  1669.  
  1670.     TOUCH
  1671.     Usage    : touch file1 .. fileN
  1672.  
  1673.     Sets DateStamp on the specified files to the current date and time.
  1674.  
  1675.     UNALIAS
  1676.     Usage    : unalias name .. name
  1677.     Example    : unalias vt
  1678.  
  1679.     Delete aliases..
  1680.  
  1681.     UNSET
  1682.     Usage    : unset name .. name
  1683.     Example    : unset abc
  1684.  
  1685.     Unset one or more variables.  Deletes them entirely.
  1686.  
  1687.     VER
  1688.     Usage    : ver
  1689.  
  1690.     Show current version name, & authors.
  1691.  
  1692.     WINDOW
  1693.     Usage    : window [-q][-f][-b][-l][-s] [dimensions]
  1694.     Options    :
  1695.         -f    (front) Window to front
  1696.         -b    (back)  Window to back
  1697.         -l    (large) Window to maximum size
  1698.         -s    (small) Window to minimum size
  1699.         -a    (activate)
  1700.         -q    (query) Lists screens and windows open
  1701.  
  1702.     Various operations on CLI window. If dimensions are specified,
  1703.     they must be in the form x y width height, with values separated
  1704.     by spaces.
  1705.     The command "window -l" may be very useful on PAL machines to
  1706.     get a full PAL window from your login sequence, or if you use
  1707.     overscan WorkBench.
  1708.     Option -q gives, for each Screen and Window currently open,
  1709.     title, left edge, top edge, width, height.
  1710.  
  1711.  
  1712. IX. SPECIAL SET VARIABLES
  1713.     ---------------------
  1714.  
  1715.     _prompt
  1716.     This variable is set to the string you wish printed as your
  1717.     prompt. This can contain escape sequences if you wish, or
  1718.     you can include a %p in path definition to get CD in your
  1719.     prompt.
  1720.     Default prompt shows path specification in red pen, followed by
  1721.     a greater (>) sign and a space.
  1722.     The if command will set the prompt to a '_ ' if commands are
  1723.     disabled while waiting for a 'endif' or 'else' command. Interactive
  1724.     mode only.
  1725.  
  1726.     _history
  1727.     This variable is set to a numerical value, and specifies how far
  1728.     back your history should extend.
  1729.  
  1730.     _debug
  1731.     Debug mode... use it if you dare.  must be set to some value
  1732.  
  1733.     _verbose
  1734.     Verbose mode (for source files).  display commands as they are
  1735.     executed.
  1736.  
  1737.     _maxerr
  1738.     The worst (highest) return value to date.  To use this, you usually
  1739.     set it to '0', then do some set of commands, then check it.
  1740.  
  1741.     _lasterr
  1742.     Return code of last command executed.  This includes internal
  1743.     commands as well as external comands, so to use this variables
  1744.     you must check it IMMEDIATELY after the command in question.
  1745.  
  1746.     _cwd
  1747.     Holds a string representing the current directory we are in from
  1748.     root.  The SHELL can get confused as to its current directory if
  1749.     some external program changes the directory.  Use PWD to rebuild
  1750.     the _cwd variable in these cases.
  1751.  
  1752.     _passed
  1753.     This variable contains the passed arguments when you SOURCE a file
  1754.     or execute a .sh file.  For instance:
  1755.  
  1756.     test a b c d
  1757.  
  1758.     -------- file test.sh ----------
  1759.     echo $_passed
  1760.     foreach i ( $_passed ) "echo YO $i"
  1761.     --------------------------------
  1762.  
  1763.     _path
  1764.     This variable contains the search path when the shell is looking
  1765.     for external commands.  The format is:  DIR,DIR,DIR  Each DIR must
  1766.     have a trailing ':' or '/'.  The current directory is always
  1767.     searched first.  The entire path will be searched first for the
  1768.     <command>, then for <command>.sh (automatic shell script sourcing).
  1769.  
  1770.     The default _path is set to
  1771.         ram:,ram:c/,df0:c/,df1:c/,df0:,df1:,sys:system/
  1772.  
  1773.     _insert
  1774.     Sets the default for insert/overtype mode for command line
  1775.     editing. ^A toggles between, but after <RET> the default is
  1776.     set back as indicated by this variable. By default _insert is 1
  1777.     indicating insert mode on setting to zero will make overtype
  1778.     the default.
  1779.  
  1780.     _titlebar
  1781.     Used to set window's title bar.
  1782.  
  1783.     _clinumber
  1784.     Contains the number (1-20) of current CLI.
  1785.  
  1786. X.  ADVANCED TOPICS
  1787.     ---------------
  1788.  
  1789.     EXCEPTION_PROCESSING:
  1790.  
  1791.     if no _except variable exists, any command which fails causes the
  1792.     rest of the line to abort as if an ABORTLINE had been executed.  If
  1793.     the _except variable exists, it is of the form:
  1794.  
  1795.     "nnn;commands..."
  1796.  
  1797.     where nnn is some value representing the minimum return code required
  1798.     to cause an error.  Whenever a command returns a code which is
  1799.     larger or equal to nnn, the commands in _except are executed before
  1800.     anything.  WHEN _except EXISTS, THE COMMAND LINE DOES NOT ABORT
  1801.     AUTOMATICALLY.  Thus, if you want the current line being executed
  1802.     to be aborted, the last command in _except should be an "abortline".
  1803.  
  1804.     exception handling is disabled while in the exception handling routine
  1805.     (thus you can't get into any infinite loops this way).
  1806.  
  1807.     Thus if _except = ";", return codes are completely ignored.
  1808.  
  1809.     example:
  1810.  
  1811.     set _except "20;abortline"
  1812.  
  1813. XI. EXAMPLE LOGIN FILE
  1814.     ------------------
  1815.  
  1816. If from a CLI or the startup-script you say 'SHELL filename', that file is
  1817. sourced first.
  1818. If you are a CLI user, your startup-sequence may be as simple as:
  1819.  
  1820.     C:Shell S:login.sh
  1821.  
  1822. Here is, my startup code:
  1823.  
  1824. ### Example S:login.sh ###
  1825.  
  1826. window -l    # if you are on a PAL machine, or use overscan
  1827.  
  1828. set _prompt ^[[33m[$_clinumber].%p>" "
  1829.  
  1830. set F5 "cdir WORK:"^M
  1831. set f9 "ed s:login.sh"^M
  1832. set F9 "ed df0:s/startup-sequence"^M
  1833. alias toram  "%q foreach i ( $q ) \"cp -r $i: ram:$i >NIL:;\
  1834.     assign $i: ram:$i\""
  1835. alias ramop  "md RAM:op; assign OP: ram:op"
  1836. alias noop   "assign OP: ; rm -r ram:op"
  1837. alias newop  "rm -r OP:*"
  1838. alias dc     "dfc df0: to df1:"
  1839. alias go     "%q assign WORK: Boot:$q; cd WORK:; source startme.sh"
  1840. alias get    "%q cp $q RAM: >NIL:"
  1841.  
  1842. assign LC:    Stuff:c
  1843. assign INCLUDE:    Stuff:include
  1844. assign LIB:    Boot:lib
  1845. assign QUAD:    RAM:
  1846.  
  1847. rback C:FaccII; sleep 1
  1848.     # after spawning a process, it is always better to allow it
  1849.     # to load the command, to avoid excessive drive head movement
  1850.  
  1851. C:REZ Blink CC LC1 LC2 >NIL:
  1852.  
  1853. C:PopCli 300 C:Newcli
  1854. C:FF -1 Siesta.font >NIL:
  1855. C:Patch_1 >NIL:
  1856. stack 8000    # lc1 and lc2 need this
  1857.  
  1858. source S:setdate.sh    # this is listed in next chapter
  1859.  
  1860. ### End of example login.sh ###
  1861.  
  1862.  
  1863. XII.  Example Source file
  1864.       -------------------
  1865.  
  1866. The following is an example source file to set date and time; it may be
  1867. used at startup if you don't have an internal clock.
  1868.  
  1869. ### setdate.sh ###
  1870.  
  1871. open CON:200/100/440/80/SetDate write 1
  1872. echo >.1 -n "Current date is "
  1873. date >.1
  1874. echo >.1 -n "Please enter date: "
  1875. input <.1 d
  1876. close 1
  1877. strlen len $d
  1878. if -r $len 1 > ; date $d ; endif
  1879. echo -n "New date: " ; date
  1880.  
  1881. ### End of setdate.sh ###
  1882.  
  1883. Next comes a makefile that needs no Make program: may be executed from
  1884. Shell directely!!!
  1885.  
  1886. ### make.sh ###
  1887.  
  1888. if -t Shell.syms Shell.h; cc +HShell.syms Shell.h; rm shell.o; endif
  1889. if -t RAM:Shell.syms Shell.syms; cp -d Shell.syms RAM:; endif
  1890.  
  1891. foreach i ( main comm1 comm2 comm3 execom globals rawconsole run set \
  1892.  sub ) "if -t $i.o $i.c; echo Compile $i...;cc +IRAM:shell.syms $i.c; endif"
  1893.  
  1894. if -t Shell run.o main.o comm1.o comm2.o comm3.o execom.o \
  1895. set.o sub.o globals.o rawconsole.o
  1896.             ln  +q -m -o Shell run.o main.o comm1.o comm2.o comm3.o\
  1897.         execom.o set.o sub.o globals.o rawconsole.o -la -lc
  1898. endif
  1899.  
  1900. ### End of make.sh ###
  1901.  
  1902.  
  1903. XIII.  Default Values
  1904.        --------------
  1905.  
  1906. To make things easier, some aliases are predefined whenever you start a
  1907. new Shell. These are:
  1908.  
  1909.     - cls
  1910.     Simply clear the screen.
  1911.  
  1912.     - cdir
  1913.     Use "cdir directory" to clear the screen, set CD to directory,
  1914.     and list it.
  1915.  
  1916.     - kr
  1917.     Deletes everything on RAM:. If you think this is dangerous,
  1918.     you can remove this alias.
  1919.  
  1920.     - exit
  1921.     Leave Shell and exit CLI.
  1922.  
  1923. Moreover, many variables have default values, and many function keys are
  1924. predefined. You can use set command to determine all of these.
  1925.  
  1926. XIV.  Why ARP ?
  1927.       ---------
  1928.  
  1929. For those of you curious enough, the A in "3.xxA" means ARP. The most
  1930. recent versions of Shell use ARP.library. This has been very useful in:
  1931.  
  1932.  - Implementing commands like ASET, ASSIGN, INFO, RESIDENT, RBACK, RUN.
  1933.  - Keeping executable code small.
  1934.  
  1935. ARP.library is really public domain, so one can include it in any package,
  1936. both commercial or public domain, like I am doing with Shell.
  1937. The ARP team is trying to wipe out the BCPL from AMIGA. This is a very
  1938. good idea, I think. And there is a lot of people hoping that Commodore
  1939. will put ARP.library in ROM, before or after. This would  make the AMIGA
  1940. a very mory friendly computer to use and program.
  1941. I encourage programmers to get ARP development package: you can find it
  1942. on many BBS, and is really public domain. Users can look for a replacement
  1943. of C: commands from ARP (but, of course, if you use this Shell you won't
  1944. need them anymore, except for ARUN).
  1945. SHAR_EOF
  1946. #    End of shell archive
  1947. exit 0
  1948. -- 
  1949. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  1950. Have five nice days.
  1951.